package com.seven.netty.protocol.codec;

import com.seven.netty.protocol.bean.Body;
import com.seven.netty.protocol.bean.Message;
import com.seven.netty.protocol.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @author chendongdong
 * @description 数据编码器
 * @since 2024/3/6 10:33
 */
@Slf4j
public class MessageEncoder extends MessageToByteEncoder<Message> {
    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Message message, ByteBuf byteBuf) throws Exception {
        log.debug("encode message = {}", message.toString());
        byteBuf.writeInt(message.getHead().getHeadIndex());//4
        byteBuf.writeInt(message.getHead().getCrcCode());//4
        byteBuf.writeByte(message.getHead().getVersion());//1
        byteBuf.writeLong(message.getHead().getSessionId());//8
        byteBuf.writeByte(message.getHead().getMessageType());//1
        byteBuf.writeInt(message.getHead().getLength());//4
        //22+2+4+4
        Map<String, Object> attachments = message.getHead().getAttachments();
        if (attachments != null && !attachments.isEmpty()) {
            byteBuf.writeShort(attachments.size());
            for (Map.Entry<String, Object> entrys : attachments.entrySet()) {
                String key = entrys.getKey();
                byteBuf.writeInt(key.length());
                byteBuf.writeCharSequence(key, StandardCharsets.UTF_8);

                Object val = entrys.getValue();
                byte[] bytes = ByteUtil.toByteArray(val);
                byteBuf.writeInt(bytes.length);
                byteBuf.writeBytes(bytes);
            }
        } else {
            //附加信息就算是NULL 也给0占位
            byteBuf.writeShort(0);
        }

        Body body = message.getBody();
        if (body != null) {
            Object payload = body.getPayload();
            if (payload != null) {
                byte[] bodyBytes = ByteUtil.toByteArray(payload);
                byteBuf.writeBytes(bodyBytes);
            }
        }
        log.debug("encode message success");
    }
}
